package com.xjrsoft.module.app.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.db.Db;
import cn.hutool.db.meta.MetaUtil;
import cn.hutool.db.meta.Table;
import cn.hutool.json.JSON;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.core.toolkit.StringPool;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.github.yulichang.base.MPJBaseServiceImpl;
import com.xjrsoft.common.constant.GlobalConstant;
import com.xjrsoft.common.enums.FormTemplateType;
import com.xjrsoft.common.enums.YesOrNoEnum;
import com.xjrsoft.common.exception.MyException;
import com.xjrsoft.common.model.generator.ComponentConfig;
import com.xjrsoft.common.model.result.R;
import com.xjrsoft.common.utils.DatasourceUtil;
import com.xjrsoft.config.GeneratePathConfig;
import com.xjrsoft.module.app.dto.AddAppMenuDto;
import com.xjrsoft.module.app.dto.AddFuncDesignDto;
import com.xjrsoft.module.app.dto.UpdateAppFuncDesignDto;
import com.xjrsoft.module.app.entity.*;
import com.xjrsoft.module.app.mapper.AppFuncDesignMapper;
import com.xjrsoft.module.app.mapper.AppMenuMapper;
import com.xjrsoft.module.app.service.*;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xjrsoft.module.form.entity.FormDesignConfig;
import com.xjrsoft.module.form.entity.FormTemplate;
import com.xjrsoft.module.form.service.IFormTemplateService;
import com.xjrsoft.module.generator.constant.ComponentTypeConstant;
import com.xjrsoft.module.generator.dto.GeneratorAppDto;
import com.xjrsoft.module.generator.entity.*;
import com.xjrsoft.module.generator.service.IGeneratorService;
import com.xjrsoft.module.generator.utils.GeneratorUtil;
import com.xjrsoft.module.generator.utils.SqlUtil;
import com.xjrsoft.module.system.entity.MenuButton;
import com.xjrsoft.module.system.entity.MenuColumn;
import com.xjrsoft.module.system.entity.MenuForm;
import com.xjrsoft.module.system.service.IDatabaselinkService;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.SneakyThrows;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.BooleanUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.sql.DataSource;
import java.io.File;
import java.io.FileNotFoundException;
import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author tzx
 * @since 2023-07-26
 */
@Service
@AllArgsConstructor
public class AppFuncDesignServiceImpl extends MPJBaseServiceImpl<AppFuncDesignMapper, AppFuncDesign> implements IAppFuncDesignService {


    private final AppMenuMapper appMenuMapper;

    private final IGeneratorService generatorService;

    private final GeneratePathConfig generatePathConfig;

    private final IDatabaselinkService databaselinkService;

    private final IAppMenuButtonService appMenuButtonService;

    private final IAppMenuColumnService appMenuColumnService;

    private final IAppMenuFormService appMenuFormService;

    private final IAppAuthorizeService appAuthorizeService;



    @Override
    @SneakyThrows
    @Transactional(rollbackFor = Exception.class)
    public Boolean add(AddFuncDesignDto dto) {

        AppFuncDesign appFuncDesign = BeanUtil.toBean(dto, AppFuncDesign.class);


        //如果是自定义表单  不需要生成代码 以及 page.json
        if (dto.getFormType() == FormTemplateType.CUSTOM.getCode() && dto.getIsGeneratorCode() != YesOrNoEnum.YES.getCode()) {
            GeneratorConfig generatorConfig = JSONUtil.toBean(dto.getJsonContent(), GeneratorConfig.class);
            AppMenu appMenu = BeanUtil.toBean(dto.getMenuConfigs(), AppMenu.class);


            long snowflakeNextId = IdUtil.getSnowflakeNextId();
            appMenu.setUrl(appMenu.getUrl() + StringPool.QUESTION_MARK + "id=" + snowflakeNextId);

            appMenuMapper.insert(appMenu);
            insertAppMenuConfig(generatorConfig,appMenu,false);

            appFuncDesign.setId(snowflakeNextId);
            appFuncDesign.setAppMenuId(appMenu.getId());
            save(appFuncDesign);

        } else {
            GeneratorConfig generatorConfig = JSONUtil.toBean(dto.getJsonContent(), GeneratorConfig.class);
            if(dto.getFormType() == FormTemplateType.CUSTOM.getCode()){
                generatorEndCode(generatorConfig);
            }
            AppMenu appMenu = BeanUtil.toBean(dto.getMenuConfigs(), AppMenu.class);


            appMenu.setUrl("/pages/" + dto.getCodes().getOutputValue() + StringPool.SLASH + dto.getCodes().getClassName().toLowerCase() + StringPool.SLASH + "list");
            appMenuMapper.insert(appMenu);
            insertAppMenuConfig(generatorConfig,appMenu,true);

            appFuncDesign.setAppMenuId(appMenu.getId());
            save(appFuncDesign);

            //保存成功之后  生成代码
            modifyPageJsonFile(dto.getCodes(), dto.getMenuConfigs());

            generatorService.generateAppCodes(dto.getCodes());
        }
        return Boolean.TRUE;
    }

    /**
     * 插入app端默认菜单数据
     * @param generatorConfig
     * @param appMenu
     * @param isUnderlineToCamel 是否需要转驼峰，自定义表单不需要生成代码不转驼峰，其它都转
     * @return
     */
    private Boolean insertAppMenuConfig(GeneratorConfig generatorConfig,AppMenu appMenu,boolean isUnderlineToCamel){
        List<ButtonConfig> buttonConfigs = generatorConfig.getListConfig().getButtonConfigs();
        List<AppMenuButton> oldBtnList = appMenuButtonService.list(Wrappers.lambdaQuery(AppMenuButton.class)
                .select(AppMenuButton::getId, AppMenuButton::getCode).eq(AppMenuButton::getMenuId, appMenu.getId()));
        Map<String, Long> btnCodeIdMap = oldBtnList.stream().collect(Collectors.toMap(m ->
                StringUtils.defaultIfBlank(StringUtils.substringAfterLast(m.getCode(), StringPool.COLON), m.getCode()), AppMenuButton::getId));

        List<AppMenuButton> btnList = new ArrayList<>();
        buttonConfigs.forEach(buttonConfig -> {
            String code = StringPool.EMPTY;
            if (BooleanUtils.isTrue(buttonConfig.getIsUse())) {
                code = buttonConfig.getCode();
                AppMenuButton menuButton = new AppMenuButton();
                menuButton.setId(btnCodeIdMap.get(StringUtils.defaultIfBlank(StringUtils.substringAfterLast(code, StringPool.COLON), code)));
                menuButton.setMenuId(appMenu.getId());
                menuButton.setName(buttonConfig.getName());
                menuButton.setCode(code);
                menuButton.setIcon(buttonConfig.getIcon());
                btnList.add(menuButton);
            }
        });

        List<ColumnConfig> columnConfigs = generatorConfig.getListConfig().getColumnConfigs();
        List<AppMenuColumn> oldColList = appMenuColumnService.list(Wrappers.lambdaQuery(AppMenuColumn.class)
                .select(AppMenuColumn::getId, AppMenuColumn::getCode).eq(AppMenuColumn::getMenuId, appMenu.getId()));
        Map<String, Long> colCodeIdMap = oldColList.stream().collect(Collectors.toMap(AppMenuColumn::getCode, AppMenuColumn::getId));
        List<AppMenuColumn> colList = new ArrayList<>();
        for (ColumnConfig columnConfig : columnConfigs) {
            AppMenuColumn menuColumn = new AppMenuColumn();
            menuColumn.setMenuId(appMenu.getId());
            menuColumn.setName(columnConfig.getLabel());
            String code = columnConfig.getColumnName();
            if (isUnderlineToCamel){//转驼峰
                code = com.baomidou.mybatisplus.core.toolkit.StringUtils.underlineToCamel(columnConfig.getColumnName());
                menuColumn.setId(colCodeIdMap.get(com.baomidou.mybatisplus.core.toolkit.StringUtils.underlineToCamel(columnConfig.getColumnName())));
            }else {
                menuColumn.setId(colCodeIdMap.get(columnConfig.getColumnName()));
            }
            menuColumn.setCode(code);
            colList.add(menuColumn);
        }
        List<ComponentConfig> componentConfigList = GeneratorUtil.getFormComponentListWithoutLayout(generatorConfig.getFormJson().getList());
        List<AppMenuForm> oldFormList = appMenuFormService.list(Wrappers.lambdaQuery(AppMenuForm.class)
                .select(AppMenuForm::getId, AppMenuForm::getCode).eq(AppMenuForm::getMenuId, appMenu.getId()));
        Map<String, Long> formCodeIdMap = oldFormList.stream().collect(Collectors.toMap(m -> m.getParentId() + StringPool.AMPERSAND + m.getCode(), AppMenuForm::getId));
        List<AppMenuForm> formList = new ArrayList<>();
        for (ComponentConfig componentConfig : componentConfigList) {
            String type = componentConfig.getType();
            if (StrUtil.equalsIgnoreCase(type, ComponentTypeConstant.SUB_FORM) || StrUtil.equalsIgnoreCase(type, ComponentTypeConstant.ONE_FOR_ONE_FORM)) {
                Long oldId = formCodeIdMap.get(StringPool.ZERO + StringPool.AMPERSAND + StrUtil.toCamelCase(componentConfig.getBindTable()));
                long id = oldId == null ? IdUtil.getSnowflakeNextId() : oldId;
                IdWorker.getId();
                AppMenuForm menuForm = new AppMenuForm();
                menuForm.setId(id);
                menuForm.setMenuId(appMenu.getId());
                if (isUnderlineToCamel){
                    menuForm.setCode(StrUtil.toCamelCase(componentConfig.getBindTable()));
                }else {
                    menuForm.setCode(componentConfig.getBindTable());
                }
                menuForm.setName(componentConfig.getLabel());
                formList.add(menuForm);
                for (ComponentConfig subConfig : componentConfig.getChildren()) {
                    AppMenuForm form = buildAppMenuForm(id, appMenu.getId(), subConfig,isUnderlineToCamel);
                    form.setId(formCodeIdMap.get(id + StringPool.AMPERSAND + form.getCode()));
                    formList.add(form);
                }
            } else {
                AppMenuForm form = buildAppMenuForm(0L, appMenu.getId(), componentConfig,isUnderlineToCamel);
                form.setId(formCodeIdMap.get(StringPool.ZERO + StringPool.AMPERSAND + form.getCode()));
                formList.add(form);
            }
        }
        List<Long> oldAppAuthIds = new ArrayList<>();
        oldAppAuthIds.add(appMenu.getId());
        List<AppMenuButton> appMenuButtonList = appMenuButtonService.list(Wrappers.lambdaQuery(AppMenuButton.class).select(AppMenuButton::getId).eq(AppMenuButton::getMenuId, appMenu.getId()));
        if (appMenuButtonList.size() > 0){
            List<Long> oldButtonIds = appMenuButtonList.stream().map(AppMenuButton::getId).collect(Collectors.toList());
            //删除之前的按钮信息
            appMenuButtonService.removeByIds(oldButtonIds);
            oldAppAuthIds.addAll(oldButtonIds);
        }
        List<AppMenuColumn> appMenuColumnList = appMenuColumnService.list(Wrappers.lambdaQuery(AppMenuColumn.class).select(AppMenuColumn::getId).eq(AppMenuColumn::getMenuId, appMenu.getId()));
        if (appMenuColumnList.size() > 0){
            List<Long> oldColumnIds = appMenuColumnList.stream().map(AppMenuColumn::getId).collect(Collectors.toList());
            appMenuColumnService.removeByIds(oldColumnIds);
            oldAppAuthIds.addAll(oldColumnIds);
        }

        List<AppMenuForm> appMenuFormList = appMenuFormService.list(Wrappers.lambdaQuery(AppMenuForm.class).select(AppMenuForm::getId).eq(AppMenuForm::getMenuId, appMenu.getId()));
        if (appMenuFormList.size() > 0){
            List<Long> oldFormIds = appMenuFormList.stream().map(AppMenuForm::getId).collect(Collectors.toList());
            appMenuFormService.removeByIds(oldFormIds);
            oldAppAuthIds.addAll(oldFormIds);
        }

        //删除之前的授权信息
        if (oldAppAuthIds.size() > 0){
            appAuthorizeService.remove(Wrappers.lambdaQuery(AppAuthorize.class).in(AppAuthorize::getObjectId,oldAppAuthIds));
        }
        appMenuButtonService.saveBatch(btnList);
        appMenuColumnService.saveBatch(colList);
        appMenuFormService.saveBatch(formList);

        return true;
    }


    private AppMenuForm buildAppMenuForm(Long parentId, Long menuId, ComponentConfig componentConfig,boolean isUnderlineToCamel) {
        String field = null;
        String type = componentConfig.getType();
        if (StrUtil.equalsIgnoreCase(type, ComponentTypeConstant.DATE_RANGE)
                || StrUtil.equalsIgnoreCase(type, ComponentTypeConstant.TIME_RANGE)) {
            if (isUnderlineToCamel){
                field = com.baomidou.mybatisplus.core.toolkit.StringUtils.underlineToCamel(componentConfig.getBindStartTime()) + StringPool.COMMA + com.baomidou.mybatisplus.core.toolkit.StringUtils.underlineToCamel(componentConfig.getBindEndTime());
            }else {
                field = componentConfig.getBindStartTime() + StringPool.COMMA + componentConfig.getBindEndTime();
            }
        } else {
            if (isUnderlineToCamel){
                field = StrUtil.isEmpty(componentConfig.getBindField()) ? componentConfig.getKey() : com.baomidou.mybatisplus.core.toolkit.StringUtils.underlineToCamel(componentConfig.getBindField());
            }else {
                field = StrUtil.isEmpty(componentConfig.getBindField()) ? componentConfig.getKey() : componentConfig.getBindField();
            }
        }
        Boolean isRequired = MapUtils.getBoolean(componentConfig.getOptions(), "required", Boolean.FALSE);
        AppMenuForm subMenuForm = new AppMenuForm();
        subMenuForm.setParentId(parentId);
        subMenuForm.setMenuId(menuId);
        subMenuForm.setCode(field);
        subMenuForm.setName(componentConfig.getLabel());
        subMenuForm.setIsRequired(isRequired ? YesOrNoEnum.YES.getCode() : YesOrNoEnum.NO.getCode());
        return subMenuForm;
    }

    @Override
    @SneakyThrows
    @Transactional(rollbackFor = Exception.class)
    public Boolean modify(UpdateAppFuncDesignDto dto) {

        AppFuncDesign appFuncDesign = BeanUtil.toBean(dto, AppFuncDesign.class);

        //如果是自定义表单  不需要生成代码 以及 page.json
        if (dto.getFormType() == FormTemplateType.CUSTOM.getCode() && dto.getIsGeneratorCode() != YesOrNoEnum.YES.getCode()) {
            GeneratorConfig generatorConfig = JSONUtil.toBean(dto.getJsonContent(), GeneratorConfig.class);
            AppMenu appMenu = BeanUtil.toBean(dto.getMenuConfigs(), AppMenu.class);

            appMenu.setId(dto.getAppMenuId());
            appMenu.setUrl(appMenu.getUrl() + StringPool.QUESTION_MARK + "id=" + appFuncDesign.getId());

            appMenuMapper.updateById(appMenu);
            insertAppMenuConfig(generatorConfig,appMenu,false);

            appFuncDesign.setAppMenuId(appMenu.getId());
            updateById(appFuncDesign);

        } else {
            GeneratorConfig generatorConfig = JSONUtil.toBean(dto.getJsonContent(), GeneratorConfig.class);
            if(dto.getFormType() == FormTemplateType.CUSTOM.getCode()){
                generatorEndCode(generatorConfig);
            }

            AppMenu appMenu = BeanUtil.toBean(dto.getMenuConfigs(), AppMenu.class);

            appMenu.setId(dto.getAppMenuId());
            appMenu.setUrl("/pages/" + dto.getCodes().getOutputValue() + StringPool.SLASH + dto.getCodes().getClassName().toLowerCase() + StringPool.SLASH + "list");
            appMenuMapper.updateById(appMenu);
            insertAppMenuConfig(generatorConfig,appMenu,true);

            updateById(appFuncDesign);

            //保存成功之后  生成代码
            modifyPageJsonFile(dto.getCodes(), dto.getMenuConfigs());


            generatorService.generateAppCodes(dto.getCodes());
        }


        return Boolean.TRUE;

    }

    private void modifyPageJsonFile(GeneratorAppDto dto, AddAppMenuDto menuDto) {
        File tempFile = FileUtil.file(generatePathConfig.getAppPath() + StringPool.SLASH + "pages.json");

        JSON jsonContent = JSONUtil.readJSON(tempFile, StandardCharsets.UTF_8);

        //如果已经包含了此地址  就不再生成
        if (jsonContent.getByPath("pages").toString().contains( "pages/" + dto.getOutputValue() + StringPool.SLASH + dto.getClassName().toLowerCase() + StringPool.SLASH + "list")) {
            return;
        }

        Map<String, Object> listJsonMap = new HashMap<>();
        listJsonMap.put("path", "pages/" + dto.getOutputValue() + StringPool.SLASH + dto.getClassName().toLowerCase() + StringPool.SLASH + "list");
        Map<String, Object> listStyleMap = new HashMap<>();
        listStyleMap.put("navigationBarTitleText", menuDto.getName());
        listStyleMap.put("navigationStyle", "custom");
        listJsonMap.put("style", listStyleMap);


//        Map<String, Object> formJsonMap = new HashMap<>();
//        formJsonMap.put("path", "pages/" + dto.getOutputValue() + StringPool.SLASH + dto.getClassName().toLowerCase() + StringPool.SLASH + "form");
//        Map<String, Object> formStyleMap = new HashMap<>();
//        formStyleMap.put("navigationBarTitleText", "新增");
//        formJsonMap.put("style", formStyleMap);

        Map<String, Object> containerJsonMap = new HashMap<>();
        containerJsonMap.put("path", "pages/" + dto.getOutputValue() + StringPool.SLASH + dto.getClassName().toLowerCase() + StringPool.SLASH + "container");
        Map<String, Object> containerStyleMap = new HashMap<>();
        containerStyleMap.put("navigationBarTitleText", "新增");
        containerStyleMap.put("navigationStyle", "custom");
        containerJsonMap.put("style", containerStyleMap);

        JSONArray pages = JSONUtil.parseArray(jsonContent.getByPath("pages").toString());

        pages.add(listJsonMap);
//        pages.add(formJsonMap);
        pages.add(containerJsonMap);

        jsonContent.putByPath("pages", pages);

        FileUtil.writeString(jsonContent.toJSONString(4), tempFile, StandardCharsets.UTF_8);

        // \components\system-form\index.vue  文件修改
        String indexFilePath = generatePathConfig.getAppPath() + StringPool.SLASH +
                "components" + StringPool.SLASH + "system-form" + StringPool.SLASH + "index.vue";
        String indexFileContent = FileUtil.readUtf8String(indexFilePath);
        String newIndexFileContent = StringUtils.replace(indexFileContent, "<!--html-->", dto.getTagString());
        FileUtil.writeUtf8String(newIndexFileContent, indexFilePath);
    }


    /**
     * 根据json 生成后端代码
     * @param generatorConfig
     */
    @SneakyThrows
    private void generatorEndCode(GeneratorConfig generatorConfig){

        Optional<TableConfig> tableConfigOptional = generatorConfig.getTableConfigs().stream().filter(TableConfig::getIsMain).findFirst();
        //主表
        TableConfig mainTable;
        if (tableConfigOptional.isPresent()) {
            mainTable = tableConfigOptional.get();
        } else {
            throw new MyException("请选择主表");
        }

        OutputConfig outputConfig = generatorConfig.getOutputConfig();
        String databaseId = generatorConfig.getDatabaseId();
        if (BooleanUtils.isTrue(outputConfig.getIsDataAuth())) {
            // 添加权限字段 rule_user_id
            DataSource dataSource = DatasourceUtil.getDataSource(databaseId);
            String[] columnNames = MetaUtil.getColumnNames(dataSource, mainTable.getTableName());
            if (!ArrayUtils.contains(columnNames, GlobalConstant.AUTH_USER_ID)) {
                DbType dbType = databaselinkService.getDbType(databaseId);
                Db.use(dataSource).executeBatch(SqlUtil.buildAddDataAuthFieldSqls(dbType, mainTable.getTableName()));
            }
        }

        //修改 getTableInfos  也记得修改 FromTemplateServiceImpl 的同名方法
        List<Table> tableInfos = getTableInfos(generatorConfig);

        createCodeFile(generatorConfig, mainTable, tableInfos);
    }

    /**
     * 获取表结构信息
     *
     * @param generatorConfig
     * @return
     */
    private List<Table> getTableInfos(GeneratorConfig generatorConfig) {
        List<Table> tableInfos = new ArrayList<>();
        for (TableConfig tableConfig : generatorConfig.getTableConfigs()) {
            //判断是否为默认数据源
            if (StrUtil.equalsIgnoreCase(generatorConfig.getDatabaseId(), GlobalConstant.DEFAULT_DATASOURCE_KEY)) {
                tableInfos.add(MetaUtil.getTableMeta(DatasourceUtil.getDatasourceMaster(), tableConfig.getTableName()));
            } else {
                tableInfos.add(MetaUtil.getTableMeta(DatasourceUtil.getDataSource(generatorConfig.getDatabaseId()), tableConfig.getTableName()));
            }
        }
        return tableInfos;
    }

    /**
     * 根据配置生成文件
     *
     * @param generatorConfig
     * @param mainTable
     * @param tableInfos
     * @throws FileNotFoundException
     */
    private void createCodeFile(GeneratorConfig generatorConfig, TableConfig mainTable, List<Table> tableInfos) throws FileNotFoundException {
        String className = generatorConfig.getOutputConfig().getClassName();
        String dirValue = generatorConfig.getOutputConfig().getOutputValue();

        //---------------------------------------生成entity开始----------------------------------------------------
        {
            Map<String, String> entityCodeMap = GeneratorUtil.getEntityCode(generatorConfig, tableInfos);

            for (Map.Entry<String, String> entry : entityCodeMap.entrySet()) {
                GeneratorUtil.writeFile(GeneratorUtil.getEntityOutputDir(dirValue), entry.getKey() + StringPool.DOT_JAVA, entry.getValue());
            }
        }
        //---------------------------------------生成entity结束----------------------------------------------------


        //********************************************生成dto开始************************************************
        {
            Map<String, String> dtoMap = new HashMap<>(3);
            dtoMap.putAll(GeneratorUtil.getAddDtoCode(generatorConfig, tableInfos));
            dtoMap.putAll(GeneratorUtil.getUpdateDtoCode(generatorConfig, tableInfos));
            dtoMap.putAll(GeneratorUtil.getPageDtoCode(generatorConfig, tableInfos, mainTable));

            for (Map.Entry<String, String> entry : dtoMap.entrySet()) {
                GeneratorUtil.writeFile(GeneratorUtil.getDtoOutputDir(dirValue), entry.getKey() + StringPool.DOT_JAVA, entry.getValue());
            }
        }
        //********************************************生成dto结束************************************************

        //###############################################生成Vo开始###############################################
        {
            Map<String, String> voMap = new HashMap<>(2);
            voMap.putAll(GeneratorUtil.getPageVoCode(generatorConfig, tableInfos, mainTable));
            voMap.putAll(GeneratorUtil.getInfoVoCode(generatorConfig, tableInfos, mainTable));

            for (Map.Entry<String, String> entry : voMap.entrySet()) {
                GeneratorUtil.writeFile(GeneratorUtil.getVoOutputDir(dirValue), entry.getKey() + StringPool.DOT_JAVA, entry.getValue());
            }
        }
        //###############################################生成Vo结束###############################################


        //---------------------------------------生成三层代码开始----------------------------------------------------
        {
            Map<String, String> mapperCode = GeneratorUtil.getMapperCode(generatorConfig, tableInfos);

            for (Map.Entry<String, String> entry : mapperCode.entrySet()) {
                GeneratorUtil.writeFile(GeneratorUtil.getMapperOutputDir(dirValue), entry.getKey() + StringPool.DOT_JAVA, entry.getValue());
            }
        }

        {
            Map<String, String> serviceCode = GeneratorUtil.getServiceCode(generatorConfig, mainTable, tableInfos.size() > 1);

            for (Map.Entry<String, String> entry : serviceCode.entrySet()) {
                GeneratorUtil.writeFile(GeneratorUtil.getServiceOutputDir(dirValue), entry.getKey() + StringPool.DOT_JAVA, entry.getValue());
            }
        }

        {
            Map<String, String> serviceImplCode = GeneratorUtil.getServiceImplCode(generatorConfig, mainTable, tableInfos.size() > 1);
            for (Map.Entry<String, String> entry : serviceImplCode.entrySet()) {
                GeneratorUtil.writeFile(GeneratorUtil.getServiceImplOutputDir(dirValue), entry.getKey() + StringPool.DOT_JAVA, entry.getValue());
            }
        }

        {
            Map<String, String> controllerCode = GeneratorUtil.getControllerCode(generatorConfig, tableInfos, mainTable);
            for (Map.Entry<String, String> entry : controllerCode.entrySet()) {
                GeneratorUtil.writeFile(GeneratorUtil.getControllerOutputDir(dirValue), entry.getKey() + StringPool.DOT_JAVA, entry.getValue());
            }
        }
        //---------------------------------------生成三层代码结束----------------------------------------------------




    }
}
